package com.loansystem.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * shiro配置类
 * 必要的三个对象： ShiroFilterFactoryBean | DefaultWebSecurityManager | Realm（可以自定义，继承AuthorizingRealm类）
 */
@Configuration
public class ShiroConfig {

    //创建shiro过滤器工厂（需要设置一个DefaultWebSecuriteManager对象）
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(defaultWebSecurityManager);
        /**
         * 添加shiro内置过滤器
         * 认证相关的
         * anon	        AnonymousFilter	指定url可以匿名访问
         * authc	    FormAuthenticationFilter	基于表单的拦截器；如“/**=authc”，如果没有登录会跳到相应的登录页面登录；主要属性：usernameParam：表单提交的用户名参数名（ username）； passwordParam：表单提交的密码参数名（password）； rememberMeParam：表单提交的密码参数名（rememberMe）； loginUrl：登录页面地址（/login.jsp）；successUrl：登录成功后的默认重定向地址； failureKeyAttribute：登录失败后错误信息存储key（shiroLoginFailure）
         * authcBasic	BasicHttpAuthenticationFilter	Basic HTTP身份验证拦截器，主要属性： applicationName：弹出登录框显示的信息（application）
         * logout	    authc.LogoutFilter	退出拦截器，主要属性：redirectUrl：退出成功后重定向的地址（/）
         * user	        UserFilter	用户拦截器，用户已经身份验证/记住我登录的都可
         * 授权相关的
         * roles	    RolesAuthorizationFilter	角色授权拦截器，验证用户是否拥有所有角色；主要属性： loginUrl：登录页面地址（/login.jsp）；unauthorizedUrl：未授权后重定向的地址；示例“/admin/**=roles[admin]”
         * perms	    PermissionsAuthorizationFilter	权限授权拦截器，验证用户是否拥有所有权限；属性和roles一样；示例“/user/**=perms[“user:create”]”
         * port	        PortFilter	端口拦截器，主要属性：port（80）：可以通过的端口；示例“/test= port[80]”，如果用户访问该页面是非80，将自动将请求端口改为80并重定向到该80端口，其他路径/参数等都一样
         * rest	        HttpMethodPermissionFilter	rest风格拦截器，自动根据请求方法构建权限字符串（GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create）构建权限字符串；示例“/users=rest[user]”，会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配（所有都得匹配，isPermittedAll）
         * ssl	        SslFilter	SSL拦截器，只有请求协议是https才能通过；否则自动跳转会https端口（443）；其他和port拦截器一样
         * noSessionCreation	NoSessionCreationAuthorizationFilter	需要指定权限才能访问
         */
        Map<String, String> linkedHashMap = new LinkedHashMap<String, String>();
        //授权
        linkedHashMap.put("/user/userInfo","perms[role:user]");
        linkedHashMap.put("/user/updateUserInfo","perms[role:user]");
        linkedHashMap.put("/admin/userInfo","perms[role:admin]");
        //认证
        linkedHashMap.put("/index","authc");
        bean.setFilterChainDefinitionMap(linkedHashMap);
        bean.setLoginUrl("/");
//        bean.setSuccessUrl("/index");
        return bean;
    }

    //默认的安全管理器对象
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getUserRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //自定义用户规则
    @Bean
    public UserRealm getUserRealm() {
        return new UserRealm();
    }

    //用来整合thymeleaf shiro的
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }
}
